Function.RegisterNamespace("Test.System.Web");

[Import("../../../../Source/System.js.Web/System/Web/Style.js")]
[Fixture]
Test.System.Web.Style=function(){
    [Fixture]
    function AddClass(){
        [Fact]
        function ThrowsIfNameIsOmitted(){
            var expected="System.Web.Style.AddClass: 'name' must be convertible to String.";
        
            var actual=Record.Exception(function(){
                System.Web.Style.AddClass(null);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNameIsUndefined(){
            var expected="System.Web.Style.AddClass: 'name' must be convertible to String.";
        
            var actual=Record.Exception(function(){
                System.Web.Style.AddClass(null,undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNameIsNull(){
            var expected="System.Web.Style.AddClass: 'name' must be convertible to String.";
        
            var actual=Record.Exception(function(){
                System.Web.Style.AddClass(null,null);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNameDoesNotHaveToStringMethod(){
            var expected="System.Web.Style.AddClass: 'name' must be convertible to String.";
        
            var actual=Record.Exception(function(){
                System.Web.Style.AddClass(null,{toString:null});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function DoesNotCallHasClassIfElementIsUndefined(){        
            var targetHasClass=System.Web.Style.HasClass;
            System.Web.Style.HasClass=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Style.AddClass(undefined,"");
            System.Web.Style.HasClass=targetHasClass;
            
            Assert.False(actual);
        }

        [Fact]
        function DoesNotCallHasClassIfElementIsNull(){
            var targetHasClass=System.Web.Style.HasClass;
            System.Web.Style.HasClass=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Style.AddClass(null,"");
            System.Web.Style.HasClass=targetHasClass;
            
            Assert.False(actual);
        }

        [Fact]
        function CallsHasClassIfElementIsValidObjectReference(){        
            var targetHasClass=System.Web.Style.HasClass;
            System.Web.Style.HasClass=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Style.AddClass({},"");
            System.Web.Style.HasClass=targetHasClass;
            
            Assert.True(actual);
        }

        [Fact]
        function PassesElementToHasClass(){        
            var targetHasClass=System.Web.Style.HasClass;
            System.Web.Style.HasClass=function(node){
                actual=node;
            }
            var expected={};
            var actual=null;
            
            System.Web.Style.AddClass(expected,"");
            System.Web.Style.HasClass=targetHasClass;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesNameToHasClass(){        
            var targetHasClass=System.Web.Style.HasClass;
            System.Web.Style.HasClass=function(node,name){
                actual=name;
            }
            var expected="name";
            var actual=null;
            
            System.Web.Style.AddClass({},expected);
            System.Web.Style.HasClass=targetHasClass;
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function DoesNotChangeElementClassNameIfHasClassReturnsTrue(){
            var targetHasClass=System.Web.Style.HasClass;
            System.Web.Style.HasClass=function(node,name){
                return true;
            }
            var target={className:"className"};
            var expected=target.className;
            
            System.Web.Style.AddClass(target,expected);
            var actual=target.className;
            System.Web.Style.HasClass=targetHasClass;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsClassNameToElementIfHasClassReturnsFalse(){
            var targetHasClass=System.Web.Style.HasClass;
            System.Web.Style.HasClass=function(node,name){
                return false;
            }
            var target={className:""};
            var expected="className";
            
            System.Web.Style.AddClass(target,expected);
            var actual=target.className;
            System.Web.Style.HasClass=targetHasClass;
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function SetsClassNameIfElementHasNone(){
            var target={};
            var expected="className";
            
            System.Web.Style.AddClass(target,expected);
            var actual=target.className;

            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsClassNameToExistingClassName(){
            var target={className:"existingClassName"};
            var targetClassName="newClassName";
            var expected=String.Format("{0} {1}",target.className,targetClassName);
            
            System.Web.Style.AddClass(target,targetClassName);
            var actual=target.className;
            
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture,Skip("Not Implemented Yet.")]
    function GetOpacity(){
        [Fact]
        function WriteMe(){
            Assert.Fail();
        }
    }

    [Fixture,Skip("Not Implemented Yet.")]
    function GetStyle(){
        [Fact]
        function WriteMe(){
            Assert.Fail();
        }
    }
    
    [Fixture]
    function HasClass(){
        [Fact]
        function ThrowsIfNameIsOmitted(){
            var expected="System.Web.Style.HasClass: 'name' must be convertible to String.";
        
            var actual=Record.Exception(function(){
                System.Web.Style.HasClass(null);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNameIsUndefined(){
            var expected="System.Web.Style.HasClass: 'name' must be convertible to String.";
        
            var actual=Record.Exception(function(){
                System.Web.Style.HasClass(null,undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNameIsNull(){
            var expected="System.Web.Style.HasClass: 'name' must be convertible to String.";
        
            var actual=Record.Exception(function(){
                System.Web.Style.HasClass(null,null);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNameDoesNotHaveToStringMethod(){
            var expected="System.Web.Style.HasClass: 'name' must be convertible to String.";
        
            var actual=Record.Exception(function(){
                System.Web.Style.HasClass(null,{toString:null});
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ReturnsFalseIfElementIsUndefined(){
            var actual=System.Web.Style.HasClass(undefined,"className");
        
            Assert.False(actual);
        }

        [Fact]
        function ReturnsFalseIfElementIsNull(){
            var actual=System.Web.Style.HasClass(null,"className");
        
            Assert.False(actual);
        }

        [Fact]
        function ReturnsFalseIfElementIsBooleanFalse(){
            var actual=System.Web.Style.HasClass(false,"className");
        
            Assert.False(actual);
        }

        [Fact]
        function ReturnsFalseIfElementIsNumberZero(){
            var actual=System.Web.Style.HasClass(0,"className");
        
            Assert.False(actual);
        }
        
        [Fact]
        function ReturnsFalseIfElementIsEmptyString(){
            var actual=System.Web.Style.HasClass("","className");
        
            Assert.False(actual);
        }
        
        [Fact]
        function ReturnsFalseIfElementHasNoClassNameMember(){
            var actual=System.Web.Style.HasClass({},"className");
        
            Assert.False(actual);
        }

        [Fact]
        function ReturnsFalseIfElementClassNameDoesNotContainClassName(){
            var actual=System.Web.Style.HasClass({className:""},"className");
        
            Assert.False(actual);
        }

        [Fact]
        function ReturnsFalseIfElementClassNameContainsClassNameAsPartOfWord(){
            var actual=System.Web.Style.HasClass({className:"classNameWordOne classNameWordTwo"},"className");
        
            Assert.False(actual);
        }

        [Fact]
        function ReturnsTrueIfElementClassNameEqualsClassName(){
            var targetClassName="className";
            var target={className:targetClassName};
            
            var actual=System.Web.Style.HasClass(target,targetClassName);
        
            Assert.True(actual);
        }

        [Fact]
        function ReturnsTrueIfElementClassNameContainsClassNameAsWord(){
            var targetClassName="className";
            var target={className:String.Format("classNameWordOne {0} classNameWordTwo",targetClassName)};
            
            var actual=System.Web.Style.HasClass(target,targetClassName);
        
            Assert.True(actual);
        }
    }
    
    [Fixture]
    function RemoveClass(){
        [Fact]
        function ThrowsIfNameIsOmitted(){
            var expected="System.Web.Style.RemoveClass: 'name' must be convertible to String.";
        
            var actual=Record.Exception(function(){
                System.Web.Style.RemoveClass(null);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNameIsUndefined(){
            var expected="System.Web.Style.RemoveClass: 'name' must be convertible to String.";
        
            var actual=Record.Exception(function(){
                System.Web.Style.RemoveClass(null,undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNameIsNull(){
            var expected="System.Web.Style.RemoveClass: 'name' must be convertible to String.";
        
            var actual=Record.Exception(function(){
                System.Web.Style.RemoveClass(null,null);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNameDoesNotHaveToStringMethod(){
            var expected="System.Web.Style.RemoveClass: 'name' must be convertible to String.";
        
            var actual=Record.Exception(function(){
                System.Web.Style.RemoveClass(null,{toString:null});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function DoesNotCallHasClassIfElementIsUndefined(){        
            var targetHasClass=System.Web.Style.HasClass;
            System.Web.Style.HasClass=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Style.RemoveClass(undefined,"");
            System.Web.Style.HasClass=targetHasClass;
            
            Assert.False(actual);
        }

        [Fact]
        function DoesNotCallHasClassIfElementIsNull(){
            var targetHasClass=System.Web.Style.HasClass;
            System.Web.Style.HasClass=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Style.RemoveClass(null,"");
            System.Web.Style.HasClass=targetHasClass;
            
            Assert.False(actual);
        }

        [Fact]
        function CallsHasClassIfElementIsValidObjectReference(){        
            var targetHasClass=System.Web.Style.HasClass;
            System.Web.Style.HasClass=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Style.RemoveClass({},"");
            System.Web.Style.HasClass=targetHasClass;
            
            Assert.True(actual);
        }

        [Fact]
        function PassesElementToHasClass(){        
            var targetHasClass=System.Web.Style.HasClass;
            System.Web.Style.HasClass=function(node){
                actual=node;
            }
            var expected={};
            var actual=null;
            
            System.Web.Style.RemoveClass(expected,"");
            System.Web.Style.HasClass=targetHasClass;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesNameToHasClass(){        
            var targetHasClass=System.Web.Style.HasClass;
            System.Web.Style.HasClass=function(node,name){
                actual=name;
            }
            var expected="name";
            var actual=null;
            
            System.Web.Style.RemoveClass({},expected);
            System.Web.Style.HasClass=targetHasClass;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function DoesNotChangeElementClassNameIfHasClassReturnsFalse(){
            var targetHasClass=System.Web.Style.HasClass;
            System.Web.Style.HasClass=function(node,name){
                return false;
            }
            var target={className:"className"};
            var expected=target.className;
            
            System.Web.Style.RemoveClass(target,expected);
            var actual=target.className;
            System.Web.Style.HasClass=targetHasClass;
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function RemovesEntireClassNameFromElementClassName(){
            var targetClassName="className";
            var target={className:targetClassName};
            var expected="";

            System.Web.Style.RemoveClass(target,targetClassName);
            var actual=target.className;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function CallsObjectIsTypeToTestForRemoveAttributeFunction(){
            var targetIsType=Object.IsType;
            Object.IsType=function(targetExpected,targetActual){
                if(Object.Same(targetRemoveAttribute,targetActual)){
                    actual=true;
                }
                return targetIsType(targetExpected,targetActual);
            }
            var targetClassName="className";
            var targetRemoveAttribute=function(){/*removeAttribute*/};
            var actual=false;
            
            System.Web.Style.RemoveClass({className:targetClassName,removeAttribute:targetRemoveAttribute},targetClassName);
            Object.IsType=targetIsType;
        
            Assert.True(actual);
        }
        
        [Fact]
        function CallsRemoveAttributeIfRemovingClassNameLeavesElementClassNameEmpty(){
            var targetClassName="className";
            var target={className:targetClassName,removeAttribute:function(){
                actual=true;
            }}
            var actual=false;
            
            System.Web.Style.RemoveClass(target,targetClassName);
        
            Assert.True(actual);
        }

        [Fact]
        function RemovesClassNameWordFromElementClassName(){
            var targetClassName="className";
            var targetClassNameFormat="classNameWordOne {0}{1}classNameWordTwo";
            var target={className:String.Format(targetClassNameFormat,targetClassName," ")};
            var expected=String.Format(targetClassNameFormat,"","");

            System.Web.Style.RemoveClass(target,targetClassName);
            var actual=target.className;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function CallsStringTrimToRemoveWhiteSpace(){
            var targetClassName="className";
            var target={className:targetClassName};
            var targetStringTrim=String.Trim;
            String.Trim=function(){
                actual=true;
            }
            var actual=false;

            System.Web.Style.RemoveClass(target,targetClassName);
            String.Trim=targetStringTrim;
            
            Assert.True(actual);
        }

        [Fact]
        function PassesNewClassNameToStringTrim(){
            var targetClassName="className";
            var expected="expected ";
            var target={className:String.Format("{0}{1}",expected,targetClassName)};
            var targetStringTrim=String.Trim;
            String.Trim=function(newClassName){
                actual=newClassName;
            }
            var actual=null;

            System.Web.Style.RemoveClass(target,targetClassName);
            String.Trim=targetStringTrim;
            
            Assert.Equal(expected,actual);
        }
   
    }

    [Fixture]
    function SetOpacity(){
        [Fact]
        function CallsObjectIsTypeToTestOpacity(){
            var targetIsType=Object.IsType;
            Object.IsType=function(targetExpected,targetActual){
                if(Object.Same(targetOpacity,targetActual)){
                    actual=true;
                }
                return targetIsType(targetExpected,targetActual);
            }
            var targetOpacity=1;
            var actual=false;

            System.Web.Style.SetOpacity({},targetOpacity);
            Object.IsType=targetIsType;

            Assert.True(actual);
        }

        [Fact]
        function ThrowsIfObjectIsTypeReturnsFalseForOpacityAsNumber(){
            var targetIsType=Object.IsType;
            Object.IsType=function(targetExpected,targetActual){
                if(Object.Same(Number,targetExpected)&&Object.Same(targetOpacity,targetActual)){
                    return false;
                }
                return targetIsType(targetExpected,targetActual);
            }
            var targetOpacity="targetOpacity";
            var expected="System.Web.Style.SetOpacity: 'opacity' must be a valid Number.";

            var actual=Record.Exception(function(){
                System.Web.Style.SetOpacity({},targetOpacity);
            });
            Object.IsType=targetIsType;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfOpacityIsLessThanZero(){
            var expected="System.Web.Style.SetOpacity: 'opacity' must be a decimal value between 0 and 1.";

            var actual=Record.Exception(function(){
                System.Web.Style.SetOpacity({},-0.01);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfOpacityIsGreaterThanOne(){
            var expected="System.Web.Style.SetOpacity: 'opacity' must be a decimal value between 0 and 1.";

            var actual=Record.Exception(function(){
                System.Web.Style.SetOpacity({},1.01);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function PassesElementToObjectSetToSetOpacity(){
            var targetObjectSet=Object.Set;
            Object.Set=function(targetElt,targetSettings){
                if(Object.Same(target,targetElt)){
                    actual=targetElt;
                }
                return targetObjectSet(targetElt,targetSettings);
            }
            var target={};
            var actual=null;
            
            System.Web.Style.SetOpacity(target,1);
            Object.Set=targetObjectSet;
            
            Assert.Same(target,actual);
        }

        [Fact]
        function PassesObjectWithStyleMemberToObjectSet(){
            var targetObjectSet=Object.Set;
            Object.Set=function(targetElt,targetSettings){
                if(Object.Same(target,targetElt)){
                    actual=targetSettings.style;
                }
                return targetObjectSet(targetElt,targetSettings);
            }
            var target={};
            var actual=null;
            
            System.Web.Style.SetOpacity(target,1);
            Object.Set=targetObjectSet;
            
            Assert.NotNull(actual);
        }

        [Fact]
        function SetsOpacityOnStyleMemberPassedToObjectSet(){
            var targetObjectSet=Object.Set;
            Object.Set=function(targetElt,targetSettings){
                if(Object.Same(target,targetElt)){
                    actual=targetSettings.style.opacity;
                }
                return targetObjectSet(targetElt,targetSettings);
            }
            var target={};
            var expected=.7;
            var actual=null;
            
            System.Web.Style.SetOpacity(target,expected);
            Object.Set=targetObjectSet;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function SetsMozOpacityOnStyleMemberPassedToObjectSet(){
            var targetObjectSet=Object.Set;
            Object.Set=function(targetElt,targetSettings){
                if(Object.Same(target,targetElt)){
                    actual=targetSettings.style.MozOpacity;
                }
                return targetObjectSet(targetElt,targetSettings);
            }
            var target={};
            var expected=.7;
            var actual=null;
            
            System.Web.Style.SetOpacity(target,expected);
            Object.Set=targetObjectSet;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function SetsWebkitOpacityOnStyleMemberPassedToObjectSet(){
            var targetObjectSet=Object.Set;
            Object.Set=function(targetElt,targetSettings){
                if(Object.Same(target,targetElt)){
                    actual=targetSettings.style.WebkitOpacity;
                }
                return targetObjectSet(targetElt,targetSettings);
            }
            var target={};
            var expected=.7;
            var actual=null;
            
            System.Web.Style.SetOpacity(target,expected);
            Object.Set=targetObjectSet;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function SetsFilterAlphaOnStyleMemberPassedToObjectSet(){
            var targetObjectSet=Object.Set;
            Object.Set=function(targetElt,targetSettings){
                if(Object.Same(target,targetElt)){
                    actual=targetSettings.style.filter;
                }
                return targetObjectSet(targetElt,targetSettings);
            }
            var target={};
            var targetOpacity=.7;
            var expected=String.Format("alpha(opacity={0})",targetOpacity*100);
            var actual=null;
            
            System.Web.Style.SetOpacity(target,targetOpacity);
            Object.Set=targetObjectSet;
            
            Assert.Equal(expected,actual);
        }
    }
}